/* $Id: ScanContext.h 27 2011-09-16 13:28:08Z skagget77 $ */

/*!
 * \file
 * \author  Johan Andersson <skagget77@gmail.com>
 * \date    Mon Feb 15 20:30 2010
 * \ingroup IoCpp
 * \brief   IoCpp Scanner EDSL.
 */

#if !defined(IOCPP_SCANCONTEXT_H)
#define IOCPP_SCANCONTEXT_H

#include "IContainer.h"

#include <boost/tr1/memory.hpp>

namespace IoCpp
{
   /*!
    * \author  Johan Andersson <skagget77@gmail.com>
    * \date    Sat Oct 03 19:59 2009
    * \ingroup IoCpp
    * \sa      Scanner for information on how to use IoCpp Scanner EDSL.
    * \brief   The Scanner class, part of IoCpp Scanner EDSL.
    *
    * \details This class should only be used indirectly through the Scanner
    *          class which is the entry point to the Scanner EDSL.
    */
   class ScanContext
   {
   public :
      /*!
       * Creates a new instance of the ScanContext class.
       *
       * \param container the IoCpp container.
       */
      ScanContext( IContainerPtr container ) 
         : mContainer(container), mExecutable(false) {
      }

      /*!
       * Adds a library to the collection of libraries to scan.
       *
       * \param  library the library to add.
       * \param  optional tells whether the library is optional or required to
       *         run the software. Plugins are often optional.
       */
      void AddLibrary( const FileCollection::value_type& library, bool optional )
      {
         if(optional)
            mOptionalFiles.push_back(library);
         else
            mFiles.push_back(library);
      }

      /*!
       * Adds a path to the collection of paths to scan.
       *
       * \param  path the path to add.
       * \param  optional tells whether the path is optional or required to run
       *         the software. Plugins are often optional.
       */
      void AddPath( const PathCollection::value_type& path, bool optional )
      {
         if(optional)
            mOptionalPaths.push_back(path);
         else
            mPaths.push_back(path);
      }

      /*!
       * Adds the current executable the collection of things to be scanned.
       */
      void AddExecutable() {
         mExecutable = true;
      }

      /*!
       * Scans all added libraries and paths.
       *
       * \throws LibraryNotFoundException
       * \throws PathNotFoundException
       */
      void Scan() {
         mContainer->Scan(mFiles, mOptionalFiles, mPaths, mOptionalPaths, mExecutable);
      }

   private :
      IContainerPtr mContainer;

      FileCollection mFiles;
      FileCollection mOptionalFiles;
      PathCollection mPaths;
      PathCollection mOptionalPaths;

      bool mExecutable;
   };

   /*!
    * ScanContext pointer.
    */
   typedef std::tr1::shared_ptr<ScanContext> ScanContextPtr;
}

#endif   // IOCPP_SCANCONTEXT_H
